package com.cx.mall.consumer.handler;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.cx.mall.api.AlipayFeign;
import com.cx.mall.api.cart.CartFeign;
import com.cx.mall.api.order.OrderInfoFeign;
import com.cx.mall.api.search.SkuEsFeign;
import com.cx.mall.common.model.order.OrderInfo;
import com.cx.mall.common.model.search.SkuEs;
import com.cx.mall.common.utils.CamelCastUtils;
import com.cx.mall.common.utils.ResponseEnum;
import com.cx.mall.common.utils.ResponseVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

@Configuration
public class ConsumerHandler {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private CartFeign cartFeign;
    @Autowired
    private AlipayFeign alipayFeign;
    @Autowired
    private OrderInfoFeign orderInfoFeign;
    @Autowired
    private SkuEsFeign skuEsFeign;

    @Bean
    public Consumer<Message<String>> deleteCartInput() {
        return message -> {
            String payload = message.getPayload();
            List<String> cartIds = JSON.parseArray(payload, String.class);
            Map<String, Object> headers = message.getHeaders();
            String key = "QUE_" + (String) headers.get("ROCKET_MQ_MESSAGE_ID");
            if(redisTemplate.opsForValue().setIfAbsent(key, "1", 80, TimeUnit.SECONDS)) {
                // 初始化请求上下文, 因为feign调用需要请求头,获取请求头需要request对象
                RequestAttributes attributes = new ServletRequestAttributes(new MockHttpServletRequest());
                RequestContextHolder.setRequestAttributes(attributes);
                try {
                    cartFeign.deleteByIds(cartIds);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                } finally {
                    // 必须清理上下文
                    RequestContextHolder.resetRequestAttributes();
                }
            }
        };
    }

    /**
     * 订单支付成功，修改订单状态
     */
    @Bean
    public Consumer<Message<String>> updateOrderStatusInput() {
        return message -> {
            String payload = message.getPayload();
            Map<String, Object> headers = message.getHeaders();
            String key = "QUE_" + (String) headers.get("ROCKET_MQ_MESSAGE_ID");
            if(redisTemplate.opsForValue().setIfAbsent(key, "1", 60, TimeUnit.SECONDS)){
                // 初始化请求上下文, 因为feign调用需要请求头,获取请求头需要request对象
                RequestAttributes attributes = new ServletRequestAttributes(new MockHttpServletRequest());
                RequestContextHolder.setRequestAttributes(attributes);
                try {
                    OrderInfo orderInfo = new OrderInfo();
                    orderInfo.setOrderId(payload);
                    orderInfo.setStatus(1);
                    orderInfo.setPayType(1);//支付宝支付
                    orderInfoFeign.update(orderInfo);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                } finally {
                    // 必须清理上下文
                    RequestContextHolder.resetRequestAttributes();
                }
            }
        };
    }



    @Bean
    public Consumer<Message<String>> checkPayInput() {
        return message -> {
            String orderId = message.getPayload();
            Map<String, Object> headers = message.getHeaders();
            String key = "QUE_" + (String) headers.get("ROCKET_MQ_MESSAGE_ID");
            if(redisTemplate.opsForValue().setIfAbsent(key, "1", 60, TimeUnit.SECONDS)){
                // 初始化请求上下文, 因为feign调用需要请求头,获取请求头需要request对象
                RequestAttributes attributes = new ServletRequestAttributes(new MockHttpServletRequest());
                RequestContextHolder.setRequestAttributes(attributes);
                try {
                    // 1 检查订单状态
                    ResponseVO responseVO  = orderInfoFeign.getById(orderId);
                    if (responseVO.getCode() != ResponseEnum.SUCCESS.getCode()){
                        throw new RuntimeException(responseVO.getMessage());
                    }
                    OrderInfo orderInfo = JSON.parseObject(JSON.toJSONString(responseVO.getData()),OrderInfo.class);
                    if(orderInfo.getStatus() == 0){
                        // 2 支付回查
                        ResponseVO r = alipayFeign.query(orderId);
                        if(r.getCode() == ResponseEnum.SUCCESS.getCode()){
                            // 3 如果支付成功，修改订单状态
                            if("TRADE_SUCCESS".equals(r.getData())){
                                OrderInfo update = new OrderInfo();
                                update.setStatus(1);
                                update.setPayType(1);
                                update.setPaymentTime(LocalDateTime.now());
                                update.setOrderId(orderId);
                                orderInfoFeign.update(update);
                            }else {
                                // 4 删除订单
//                                orderFeign.removeById(orderId);
                            }
                        }

                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                } finally {
                    // 必须清理上下文
                    RequestContextHolder.resetRequestAttributes();
                }
            }
        };
    }

    @Bean
    public Consumer<Message<String>> syncSkuInfoInput() {
        return message -> {
            String payload = message.getPayload();
            // 将MQ转换中Map
            Map<String, Object> canalData = JSON.parseObject(payload, Map.class);
            // 获取SkuInfo对象集合
            List<JSONObject> data = (List<JSONObject>) canalData.get("data");
            // 获取SkuEs对象,并同步到Es
            if (data != null && data.size() > 0) {
                // 将json对象转换成SkuEs对象（驼峰转换）,CamelCastUtils自定义工具类
                SkuEs skuEs = CamelCastUtils.jsonToObject(data.get(0),SkuEs.class);
                // 获取操作类型
                String type = canalData.get("type").toString().toUpperCase();
                // 初始化请求上下文, 因为feign调用需要请求头,获取请求头需要request对象
                RequestAttributes attributes = new ServletRequestAttributes(new MockHttpServletRequest());
                RequestContextHolder.setRequestAttributes(attributes);
                if("INSERT".equals(type)){
                    skuEsFeign.save(skuEs);
                }else if ("UPDATE".equals(type)){
                    // 先删除，再添加
                    skuEsFeign.delete(skuEs.getId());
                    skuEsFeign.save(skuEs);
                }else if ("DELETE".equals(type)){
                    skuEsFeign.delete(skuEs.getId());
                }
            }
        };
    }


}
